import*as e from"../../core/common/common.js";import*as t from"../../core/host/host.js";import*as o from"../../core/platform/platform.js";import{assertNotNullOrUndefined as i}from"../../core/platform/platform.js";import*as r from"../../core/root/root.js";import*as s from"../../core/sdk/sdk.js";import*as n from"../bindings/bindings.js";import*as a from"../workspace/workspace.js";let u;class d extends e.ObjectWrapper.ObjectWrapper{storage=new h;#e;targetManager;debuggerWorkspaceBinding;#t=new Map;#o=new Map;#i=new Map;#r=[];constructor(e,t,o){super(),this.#e=t,this.targetManager=e,this.debuggerWorkspaceBinding=o,r.Runtime.experiments.isEnabled(r.Runtime.ExperimentName.SET_ALL_BREAKPOINTS_EAGERLY)&&(this.storage.mute(),this.#s(),this.storage.unmute()),this.#e.addEventListener(a.Workspace.Events.UISourceCodeAdded,this.uiSourceCodeAdded,this),this.#e.addEventListener(a.Workspace.Events.UISourceCodeRemoved,this.uiSourceCodeRemoved,this),this.#e.addEventListener(a.Workspace.Events.ProjectRemoved,this.projectRemoved,this),this.targetManager.observeModels(s.DebuggerModel.DebuggerModel,this)}#s(){for(const e of this.storage.breakpoints.values()){const t=h.computeId(e),o=new l(this,null,e,"RESTORED");this.#i.set(t,o)}}static instance(e={forceNew:null,targetManager:null,workspace:null,debuggerWorkspaceBinding:null}){const{forceNew:t,targetManager:o,workspace:i,debuggerWorkspaceBinding:r}=e;if(!u||t){if(!o||!i||!r)throw new Error(`Unable to create settings: targetManager, workspace, and debuggerWorkspaceBinding must be provided: ${(new Error).stack}`);u=new d(o,i,r)}return u}modelAdded(e){r.Runtime.experiments.isEnabled(r.Runtime.ExperimentName.INSTRUMENTATION_BREAKPOINTS)&&e.setSynchronizeBreakpointsCallback(this.restoreBreakpointsForScript.bind(this))}modelRemoved(e){e.setSynchronizeBreakpointsCallback(null)}addUpdateBindingsCallback(e){this.#r.push(e)}async copyBreakpoints(e,t){const o=t.project().uiSourceCodeForURL(t.url())!==t||this.#e.project(t.project().id())!==t.project(),i=this.storage.breakpointItems(e.url(),e.contentType().name());for(const e of i)o?this.storage.updateBreakpoint({...e,url:t.url(),resourceTypeName:t.contentType().name()}):await this.setBreakpoint(t,e.lineNumber,e.columnNumber,e.condition,e.enabled,e.isLogpoint,"RESTORED")}async restoreBreakpointsForScript(e){if(!r.Runtime.experiments.isEnabled(r.Runtime.ExperimentName.INSTRUMENTATION_BREAKPOINTS))return;if(!e.sourceURL)return;const t=await this.getUISourceCodeWithUpdatedBreakpointInfo(e);this.#n(e.sourceURL)&&await this.#a(t);const o=e.debuggerModel,s=await o.sourceMapManager().sourceMapForClientPromise(e);if(s)for(const t of s.sourceURLs())if(this.#n(t)){const i=await this.debuggerWorkspaceBinding.uiSourceCodeForSourceMapSourceURLPromise(o,t,e.isContentScript());await this.#a(i)}const{pluginManager:n}=this.debuggerWorkspaceBinding;if(n){const t=await n.getSourcesForScript(e);if(Array.isArray(t))for(const e of t)if(this.#n(e)){const t=await this.debuggerWorkspaceBinding.uiSourceCodeForDebuggerLanguagePluginSourceURLPromise(o,e);i(t),await this.#a(t)}}}async getUISourceCodeWithUpdatedBreakpointInfo(e){const t=this.debuggerWorkspaceBinding.uiSourceCodeForScript(e);return i(t),await this.#u(t),t}async#u(e){if(this.#r.length>0){const t=[];for(const o of this.#r)t.push(o(e));await Promise.all(t)}}async#a(e){this.restoreBreakpoints(e);const t=this.#i.values(),o=Array.from(t).filter((t=>t.uiSourceCodes.has(e)));await Promise.all(o.map((e=>e.updateBreakpoint())))}#n(e){return this.storage.breakpointItems(e).length>0}static getScriptForInlineUiSourceCode(e){const t=n.DefaultScriptMapping.DefaultScriptMapping.scriptForUISourceCode(e);return t&&t.isInlineScript()&&!t.hasSourceURL?t:null}static breakpointLocationFromUiLocation(e){const t=e.uiSourceCode,o=d.getScriptForInlineUiSourceCode(t),{lineNumber:i,columnNumber:r}=o?o.relativeLocationToRawLocation(e):e;return{lineNumber:i,columnNumber:r}}static uiLocationFromBreakpointLocation(e,t,o){const i=d.getScriptForInlineUiSourceCode(e);return i&&({lineNumber:t,columnNumber:o}=i.rawLocationToRelativeLocation({lineNumber:t,columnNumber:o})),e.uiLocation(t,o)}static isValidPositionInScript(e,t,o){return!o||!(e<o.lineOffset||e>o.endLine)&&(!(e===o.lineOffset&&t&&t<o.columnOffset)&&!(e===o.endLine&&(!t||t>=o.endColumn)))}restoreBreakpoints(e){const t=d.getScriptForInlineUiSourceCode(e),o=t?.sourceURL??e.url();if(!o)return;const i=e.contentType();this.storage.mute();const r=this.storage.breakpointItems(o,i.name());for(const o of r){const{lineNumber:i,columnNumber:r}=o;d.isValidPositionInScript(i,r,t)&&this.innerSetBreakpoint(e,i,r,o.condition,o.enabled,o.isLogpoint,"RESTORED")}this.storage.unmute()}uiSourceCodeAdded(e){const t=e.data;this.restoreBreakpoints(t)}uiSourceCodeRemoved(e){const t=e.data;this.removeUISourceCode(t)}projectRemoved(e){const t=e.data;for(const e of t.uiSourceCodes())this.removeUISourceCode(e)}removeUISourceCode(e){this.#d(e).forEach((t=>t.removeUISourceCode(e)))}async setBreakpoint(t,o,i,r,s,n,u){const c=this.#e.findCompatibleUISourceCodes(t);let l;for(const p of c){const c=new a.UISourceCode.UILocation(p,o,i),h=await this.debuggerWorkspaceBinding.normalizeUILocation(c),g=d.breakpointLocationFromUiLocation(h),b=this.innerSetBreakpoint(h.uiSourceCode,g.lineNumber,g.columnNumber,r,s,n,u);t===p&&(h.id()!==c.id()&&e.Revealer.reveal(h),l=b)}return console.assert(void 0!==l,"The passed uiSourceCode is expected to be a valid uiSourceCode"),l}innerSetBreakpoint(e,t,o,i,r,s,n){const a={url:d.getScriptForInlineUiSourceCode(e)?.sourceURL??e.url(),resourceTypeName:e.contentType().name(),lineNumber:t,columnNumber:o,condition:i,enabled:r,isLogpoint:s},u=h.computeId(a);let c=this.#i.get(u);return c?(c.updateState(a),c.addUISourceCode(e),c.updateBreakpoint(),c):(c=new l(this,e,a,n),this.#i.set(u,c),c)}findBreakpoint(e){const t=this.#o.get(e.uiSourceCode);return t&&t.get(e.id())||null}addHomeUISourceCode(e,t){let o=this.#t.get(e);o||(o=new Set,this.#t.set(e,o)),o.add(t)}removeHomeUISourceCode(e,t){const o=this.#t.get(e);o&&(o.delete(t),0===o.size&&this.#t.delete(e))}async possibleBreakpoints(e,t){const o=await this.debuggerWorkspaceBinding.uiLocationRangeToRawLocationRanges(e,t),i=(await Promise.all(o.map((({start:e,end:t})=>e.debuggerModel.getPossibleBreakpoints(e,t,!1))))).flat(),r=new Map;return await Promise.all(i.map((async o=>{const i=await this.debuggerWorkspaceBinding.rawLocationToUILocation(o);null!==i&&i.uiSourceCode===e&&t.containsLocation(i.lineNumber,i.columnNumber??0)&&r.set(i.id(),i)}))),[...r.values()]}breakpointLocationsForUISourceCode(e){const t=this.#o.get(e);return t?Array.from(t.values()):[]}#d(e){return this.breakpointLocationsForUISourceCode(e).map((e=>e.breakpoint)).concat(Array.from(this.#t.get(e)??[]))}allBreakpointLocations(){const e=[];for(const t of this.#o.values())e.push(...t.values());return e}removeBreakpoint(e,t){const o=e.breakpointStorageId();t&&this.storage.removeBreakpoint(o),this.#i.delete(o)}uiLocationAdded(e,t){let o=this.#o.get(t.uiSourceCode);o||(o=new Map,this.#o.set(t.uiSourceCode,o));const i=new g(e,t);o.set(t.id(),i),this.dispatchEventToListeners(c.BreakpointAdded,i)}uiLocationRemoved(e,t){const o=this.#o.get(t.uiSourceCode);if(!o)return;const i=o.get(t.id())||null;i&&(o.delete(t.id()),0===o.size&&this.#o.delete(t.uiSourceCode),this.dispatchEventToListeners(c.BreakpointRemoved,i))}supportsConditionalBreakpoints(e){return this.debuggerWorkspaceBinding.supportsConditionalBreakpoints(e)}}var c;!function(e){e.BreakpointAdded="breakpoint-added",e.BreakpointRemoved="breakpoint-removed"}(c||(c={}));class l{breakpointManager;#c=new Set;uiSourceCodes=new Set;#l;#p;isRemoved=!1;#h=null;#g=new Map;constructor(e,t,o,i){this.breakpointManager=e,this.#p=i,this.updateState(o),t?(console.assert(t.contentType().name()===o.resourceTypeName),this.addUISourceCode(t)):this.#b(o),this.breakpointManager.targetManager.observeModels(s.DebuggerModel.DebuggerModel,this)}#b(t){t.resolvedState?this.#h=t.resolvedState.map((e=>({...e,scriptHash:""}))):t.resourceTypeName===e.ResourceType.resourceTypes.Script.name()&&(this.#h=[{url:t.url,lineNumber:t.lineNumber,columnNumber:t.columnNumber,scriptHash:"",condition:this.backendCondition()}])}getLastResolvedState(){return this.#h}updateLastResolvedState(e){if(this.#h=e,!r.Runtime.experiments.isEnabled(r.Runtime.ExperimentName.SET_ALL_BREAKPOINTS_EAGERLY))return;let t;e&&(t=e.map((e=>({url:e.url,lineNumber:e.lineNumber,columnNumber:e.columnNumber,condition:e.condition})))),function(e,t){if(e===t)return!0;if(!e||!t||e.length!==t.length)return!1;for(let o=0;o<e.length;o++){const i=e[o],r=t[o];if(i.url!==r.url||i.lineNumber!==r.lineNumber||i.columnNumber!==r.columnNumber||i.condition!==r.condition)return!1}return!0}(this.#l.resolvedState,t)||(this.#l={...this.#l,resolvedState:t},this.breakpointManager.storage.updateBreakpoint(this.#l))}get origin(){return this.#p}async refreshInDebugger(){if(!this.isRemoved){const e=Array.from(this.#g.values());await Promise.all(e.map((async e=>(await e.resetBreakpoint(),this.#m(e)))))}}modelAdded(e){const t=this.breakpointManager.debuggerWorkspaceBinding,o=new p(e,this,t);this.#g.set(e,o),this.#m(o),e.addEventListener(s.DebuggerModel.Events.DebuggerWasEnabled,this.#k,this),e.addEventListener(s.DebuggerModel.Events.DebuggerWasDisabled,this.#S,this),e.addEventListener(s.DebuggerModel.Events.ScriptSourceWasEdited,this.#f,this)}modelRemoved(e){this.#g.get(e)?.cleanUpAfterDebuggerIsGone(),this.#g.delete(e),this.#L(e)}#L(e){e.removeEventListener(s.DebuggerModel.Events.DebuggerWasEnabled,this.#k,this),e.removeEventListener(s.DebuggerModel.Events.DebuggerWasDisabled,this.#S,this),e.removeEventListener(s.DebuggerModel.Events.ScriptSourceWasEdited,this.#f,this)}#k(e){const t=e.data,o=this.#g.get(t);o&&this.#m(o)}#S(e){const t=e.data;this.#g.get(t)?.cleanUpAfterDebuggerIsGone()}async#f(e){const{source:t,data:{script:o,status:i}}=e;if("Ok"!==i)return;console.assert(t instanceof s.DebuggerModel.DebuggerModel);const r=this.#g.get(t);r?.wasSetIn(o.scriptId)&&(await r.resetBreakpoint(),this.#m(r))}modelBreakpoint(e){return this.#g.get(e)}addUISourceCode(e){this.uiSourceCodes.has(e)||(this.uiSourceCodes.add(e),this.breakpointManager.addHomeUISourceCode(e,this),this.bound()||this.breakpointManager.uiLocationAdded(this,this.defaultUILocation(e)))}clearUISourceCodes(){this.bound()||this.removeAllUnboundLocations();for(const e of this.uiSourceCodes)this.removeUISourceCode(e)}removeUISourceCode(e){if(this.uiSourceCodes.has(e)&&(this.uiSourceCodes.delete(e),this.breakpointManager.removeHomeUISourceCode(e,this),this.bound()||this.breakpointManager.uiLocationRemoved(this,this.defaultUILocation(e))),this.bound()){for(const t of this.#c)t.uiSourceCode===e&&(this.#c.delete(t),this.breakpointManager.uiLocationRemoved(this,t));this.bound()||this.isRemoved||this.addAllUnboundLocations()}}url(){return this.#l.url}lineNumber(){return this.#l.lineNumber}columnNumber(){return this.#l.columnNumber}uiLocationAdded(e){this.isRemoved||(this.bound()||this.removeAllUnboundLocations(),this.#c.add(e),this.breakpointManager.uiLocationAdded(this,e))}uiLocationRemoved(e){this.#c.has(e)&&(this.#c.delete(e),this.breakpointManager.uiLocationRemoved(this,e),this.bound()||this.isRemoved||this.addAllUnboundLocations())}enabled(){return this.#l.enabled}bound(){return 0!==this.#c.size}hasBoundScript(){for(const e of this.uiSourceCodes)if(e.project().type()===a.Workspace.projectTypes.Network)return!0;return!1}setEnabled(e){this.updateState({...this.#l,enabled:e})}condition(){return this.#l.condition}backendCondition(){let e=this.condition();if(""===e)return"";let t=s.DebuggerModel.COND_BREAKPOINT_SOURCE_URL;return this.isLogpoint()&&(e=`${b}${e}${m}`,t=s.DebuggerModel.LOGPOINT_SOURCE_URL),`${e}\n\n//# sourceURL=${t}`}setCondition(e,t){this.updateState({...this.#l,condition:e,isLogpoint:t})}isLogpoint(){return this.#l.isLogpoint}get storageState(){return this.#l}updateState(e){this.#l?.enabled===e.enabled&&this.#l?.condition===e.condition&&this.#l?.isLogpoint===e.isLogpoint||(this.#l=e,this.breakpointManager.storage.updateBreakpoint(this.#l),this.updateBreakpoint())}async updateBreakpoint(){return this.bound()||(this.removeAllUnboundLocations(),this.isRemoved||this.addAllUnboundLocations()),this.#v()}async remove(e){if(this.getIsRemoved())return;this.isRemoved=!0;const t=!e;for(const e of this.#g.keys())this.#L(e);await this.#v(),this.breakpointManager.removeBreakpoint(this,t),this.breakpointManager.targetManager.unobserveModels(s.DebuggerModel.DebuggerModel,this),this.clearUISourceCodes()}breakpointStorageId(){return h.computeId(this.#l)}defaultUILocation(e){return d.uiLocationFromBreakpointLocation(e,this.#l.lineNumber,this.#l.columnNumber)}removeAllUnboundLocations(){for(const e of this.uiSourceCodes)this.breakpointManager.uiLocationRemoved(this,this.defaultUILocation(e))}addAllUnboundLocations(){for(const e of this.uiSourceCodes)this.breakpointManager.uiLocationAdded(this,this.defaultUILocation(e))}getUiSourceCodes(){return this.uiSourceCodes}getIsRemoved(){return this.isRemoved}async#v(){await Promise.all(Array.from(this.#g.values()).map((e=>this.#m(e))))}async#m(e){const t=await e.scheduleUpdateInDebugger();"ERROR_BACKEND"===t?await this.remove(!0):"ERROR_BREAKPOINT_CLASH"===t&&await this.remove(!1)}}class p{#I;#B;#R;#C=new n.LiveLocation.LiveLocationPool;#c=new Map;#U=new e.Mutex.Mutex;#N=!1;#M=null;#E=[];#w=new Set;constructor(e,t,o){this.#I=e,this.#B=t,this.#R=o}get currentState(){return this.#M}resetLocations(){for(const e of this.#c.values())this.#B.uiLocationRemoved(e);this.#c.clear(),this.#C.disposeAll(),this.#w.clear()}async scheduleUpdateInDebugger(){if(!this.#I.debuggerEnabled())return"OK";const e=await this.#U.acquire();let t="PENDING";for(;"PENDING"===t;)t=await this.#D();return e(),t}scriptDiverged(){for(const e of this.#B.getUiSourceCodes()){const t=this.#R.scriptFile(e,this.#I);if(t&&t.hasDivergedFromVM())return!0}return!1}async#D(){if(this.#I.target().isDisposed())return this.cleanUpAfterDebuggerIsGone(),"OK";const e=this.#B.lineNumber(),t=this.#B.columnNumber(),o=this.#B.backendCondition();let i=null;if(!this.#B.getIsRemoved()&&this.#B.enabled()&&!this.scriptDiverged()){let s=[];for(const o of this.#B.getUiSourceCodes()){const{lineNumber:i,columnNumber:r}=d.uiLocationFromBreakpointLocation(o,e,t);if(s=(await n.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().uiLocationToRawLocations(o,i,r)).filter((e=>e.debuggerModel===this.#I)),s.length)break}if(s.length&&s.every((e=>e.script()))){i=s.map((e=>{const t=e.script();return{url:t.sourceURL,scriptHash:t.hash,lineNumber:e.lineNumber,columnNumber:e.columnNumber,condition:o}})).slice(0)}else if(!r.Runtime.experiments.isEnabled(r.Runtime.ExperimentName.INSTRUMENTATION_BREAKPOINTS)){const r=this.#B.getLastResolvedState();if(r)i=r.map((e=>({...e,condition:o})));else{i=[{url:this.#B.url(),scriptHash:"",lineNumber:e,columnNumber:t,condition:o}]}}}const s=this.#E.length;if(s&&l.State.equals(i,this.#M))return"OK";if(this.#B.updateLastResolvedState(i),s)return await this.resetBreakpoint(),"PENDING";if(!i)return"OK";const{breakpointIds:a,locations:u,serverError:c}=await this.#y(i),p=c&&this.#I.debuggerEnabled()&&!this.#I.isReadyToPause();if(!a.length&&p)return"PENDING";if(this.#M=i,this.#N)return this.#N=!1,"OK";if(!a.length)return"ERROR_BACKEND";this.#E=a,this.#E.forEach((e=>this.#I.addBreakpointListener(e,this.breakpointResolved,this)));return(await Promise.all(u.map((e=>this.addResolvedLocation(e))))).includes("ERROR")?"ERROR_BREAKPOINT_CLASH":"OK"}async#y(e){const t=await Promise.all(e.map((e=>e.url?this.#I.setBreakpointByURL(e.url,e.lineNumber,e.columnNumber,e.condition):this.#I.setBreakpointInAnonymousScript(e.scriptHash,e.lineNumber,e.columnNumber,e.condition)))),o=[];let i=[],r=!1;for(const e of t)e.breakpointId?(o.push(e.breakpointId),i=i.concat(e.locations)):r=!0;return{breakpointIds:o,locations:i,serverError:r}}async resetBreakpoint(){this.#E.length&&(this.resetLocations(),await Promise.all(this.#E.map((e=>this.#I.removeBreakpoint(e)))),this.didRemoveFromDebugger(),this.#M=null)}didRemoveFromDebugger(){this.#N?this.#N=!1:(this.resetLocations(),this.#E.forEach((e=>this.#I.removeBreakpointListener(e,this.breakpointResolved,this))),this.#E=[])}async breakpointResolved({data:e}){"ERROR"===await this.addResolvedLocation(e)&&await this.#B.remove(!1)}async locationUpdated(e){const t=this.#c.get(e),o=await e.uiLocation();t&&this.#B.uiLocationRemoved(t),o?(this.#c.set(e,o),this.#B.uiLocationAdded(o)):this.#c.delete(e)}async addResolvedLocation(e){this.#w.add(e.scriptId);const t=await this.#R.rawLocationToUILocation(e);if(!t)return"OK";const o=this.#B.breakpointManager.findBreakpoint(t);return o&&o.breakpoint!==this.#B?"ERROR":(await this.#R.createLiveLocation(e,this.locationUpdated.bind(this),this.#C),"OK")}cleanUpAfterDebuggerIsGone(){this.#N=!0,this.resetLocations(),this.#M=null,this.#E.length&&this.didRemoveFromDebugger()}wasSetIn(e){return this.#w.has(e)}}!function(e){let t;!function(e){e.equals=function(e,t){if(e===t)return!0;if(!e||!t)return!1;if(e.length!==t.length)return!1;for(let o=0;o<e.length;o++){const i=e[o],r=t[o];if(i.url!==r.url)return!1;if(i.scriptHash!==r.scriptHash)return!1;if(i.lineNumber!==r.lineNumber)return!1;if(i.columnNumber!==r.columnNumber)return!1;if(i.condition!==r.condition)return!1}return!0}}(t=e.State||(e.State={}))}(l||(l={}));class h{setting;breakpoints;#A;constructor(){this.setting=e.Settings.Settings.instance().createLocalSetting("breakpoints",[]),this.breakpoints=new Map,this.#A=!1;for(const e of this.setting.get())this.breakpoints.set(h.computeId(e),e);t.userMetrics.breakpointsRestoredFromStorage(this.breakpoints.size)}mute(){this.#A=!0}unmute(){this.#A=!1}breakpointItems(e,t){const o=[];for(const i of this.breakpoints.values())i.url===e&&(i.resourceTypeName!==t&&void 0!==t||o.push(i));return o}updateBreakpoint(e){if(this.#A)return;const t=h.computeId(e);t&&(this.breakpoints.set(t,e),this.save())}removeBreakpoint(e){this.#A||(this.breakpoints.delete(e),this.save())}save(){this.setting.set(Array.from(this.breakpoints.values()))}static computeId({url:e,resourceTypeName:t,lineNumber:o,columnNumber:i}){if(!e)return"";let r=`${e}:${t}:${o}`;return void 0!==i&&(r+=`:${i}`),r}}class g{breakpoint;uiLocation;constructor(e,t){this.breakpoint=e,this.uiLocation=t}}const b="/** DEVTOOLS_LOGPOINT */ console.log(",m=")";var k=Object.freeze({__proto__:null,BreakpointManager:d,get Events(){return c},get Breakpoint(){return l},ModelBreakpoint:p,EMPTY_BREAKPOINT_CONDITION:"",NEVER_PAUSE_HERE_CONDITION:"false",BreakpointLocation:g});export{k as BreakpointManager};
